<template>
  <BasicTable @register="registerTable">
    <template #headerTop>
      <Alert v-if="checkedKeys.length > 0" type="info" show-icon style="position: relative">
        <template #message>
          <div>
            <span>已选中{{ checkedKeys.length }}条记录</span>
            <div style="position: absolute; top: 4px; right: 10px">
              <Tooltip title="删除">
                <a-button type="text" @click="handleSelectedDelete">
                  <Icon :icon="ICON.DELETE" color="#0960bd" />
                </a-button>
              </Tooltip>
            </div>
          </div>
        </template>
      </Alert>
    </template>
    <template #tableTitle>
      <div class="ml-2">
        <span>{{ tableTitle }}</span>
        <a-select
          style="margin-left: 10px; width: 120px"
          :options="options"
          v-model:value="optionsValue"
          @change="handleChange"
        />
      </div>
    </template>
    <template #toolbar>
      <a-button type="primary" @click="handleAdd">添加关联</a-button>
    </template>
    <template #bodyCell="{ column, record }">
      <template v-if="column.key === 'action'">
        <TableAction
          :actions="[
            {
              icon: ICON.EDIT,
              tooltip: {
                title: '编辑',
                placement: 'top',
              },
              onClick: handleEdit.bind(null, record),
            },
            {
              icon: ICON.DELETE,
              onClick: handleDelete.bind(null, record),
            },
          ]"
        />
      </template>
    </template>
  </BasicTable>
  <AddModal @register="registerAddModal" @success="handleSuccess" />
  <EditModal @register="registerEditModal" @success="handleSuccess" />
</template>
<script setup lang="ts">
  import { defineProps, ref, onMounted } from 'vue';
  import { BasicTable, useTable, TableAction } from '/@/components/Table';
  import { ICON } from '/@/enums/iconEnum';
  import { Alert, Tooltip } from 'ant-design-vue';
  import Icon from '/@/components/Icon';
  import {
    associationFromTableSchema,
    associationToTableSchema,
    associationDataFormSchema,
  } from './index.data';
  import { useModal } from '/@/components/Modal';
  import {
    getRelationByFrom,
    getRelationByTo,
    saveRelation,
    deleteRelation,
  } from '/@/api/thingsborad/entity/entity';
  import {
    relationByFromParams,
    relationByToParams,
    relationResponse,
    relationFromTableItem,
    relationToTableItem,
    saveRelationParams,
    deleteRelationParams,
  } from '/@/api/thingsborad/entity/model/entityModel';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { Select as ASelect } from 'ant-design-vue';
  import AddModal from './components/AddModal.vue';
  import EditModal from './components/EditModal.vue';
  import {
    publicDrawerTableFormStyleSetting,
    tableStyleSetting,
  } from '/@/settings/thingsBoardDesign';
  import { buildUUID } from '/@/utils/uuid';

  const props = defineProps({
    isComponent: {
      type: Boolean,
      default: true,
    },
    entityType: {
      type: String,
      default: '',
    },
    entityId: {
      type: String,
      default: '',
    },
  });

  let tableTitle = ref('向外的关联');
  const options = ref<Array<any>>([
    { label: '从', value: 'from' },
    { label: '到', value: 'to' },
  ]);
  const optionsValue = ref('from');
  // 多选删除
  const checkedKeys = ref<any>([]);

  const { createConfirm } = useMessage();
  const [registerTable, { setProps, reload, setColumns, getDataSource }] = useTable({
    ...tableStyleSetting,
    fetchSetting: {
      pageField: 'page',
      sizeField: 'pageSize',
      listField: 'data',
      totalField: 'totalElements',
    },
    pagination: { pageSizeOptions: ['10', '20', '30'] },
    formConfig: {
      layout: 'horizontal',
      schemas: associationDataFormSchema,
      ...publicDrawerTableFormStyleSetting,
      actionColOptions: {
        md: { span: 12, offset: 0 },
        lg: { span: 8, offset: 8 },
        xl: { span: 6, offset: 12 },
        xxl: { span: 6, offset: 12 },
      },
    },
  });
  const [registerAddModal, { openModal: openAddModal }] = useModal();
  const [registerEditModal, { openModal: openEditModal }] = useModal();
  // 修改
  const handleEdit = (record: Recordable) => {
    openEditModal(true, {
      record,
      id: props.entityId,
      optionsValue: optionsValue.value,
    });
  };
  // 添加
  const handleAdd = () => {
    openAddModal(true, { optionsValue: optionsValue.value });
  };

  // 删除
  function handleDelete(record: Recordable) {
    handleDeleteRelation(record);
  }

  // 多选
  function onSelect(record: Recordable, selected: boolean) {
    if (selected) {
      checkedKeys.value = [...checkedKeys.value, record.id];
    } else {
      checkedKeys.value = checkedKeys.value.filter((id: any) => id !== record.id);
    }
  }
  // 全选
  function onSelectAll(selected: boolean, _selectedRows: Recordable[], changeRows: Recordable[]) {
    const changeIds = changeRows.map((item) => item.id);
    if (selected) {
      checkedKeys.value = [...checkedKeys.value, ...changeIds];
    } else {
      checkedKeys.value = checkedKeys.value.filter((id) => {
        return !changeIds.includes(id);
      });
    }
  }
  // 多选删除
  const handleSelectedDelete = () => {
    createConfirm({
      iconType: 'info',
      title: `确定要删除实体 ${checkedKeys.value.length} 个关联吗？`,
      content: '确定删除所有选择的关联关系后，当前实体将与对应的实体取消关联',
      onOk: async () => {
        const records = getDataSource().filter((item) => checkedKeys.value.includes(item.id));
        const promises = records.map((item) => {
          let params: deleteRelationParams = {
            fromId: '',
            fromType: '',
            relationType: item.type,
            toId: '',
            toType: '',
          };
          if (item.toEntityName) {
            params.fromId = props.entityId;
            params.fromType = props.entityType;
            params.toId = item.toId;
            params.toType = item.toEntityType;
          } else {
            params.fromId = item.fromId;
            params.fromType = item.fromEntityType;
            params.toId = props.entityId;
            params.toType = props.entityType;
          }
          return deleteRelation({ ...params });
        });
        await Promise.all(promises);
        checkedKeys.value = [];
        reload();
      },
    });
  };

  // 关联表格切换
  const handleRelation = (val) => {
    let api: any;
    let beforeFetch: any;
    let afterFetch: any;
    switch (val) {
      case 'from':
        tableTitle.value = '向外的关联';
        setColumns(associationFromTableSchema);
        api = getRelationByFrom;
        beforeFetch = () => {
          let params: relationByFromParams = {
            fromId: props.entityId,
            fromType: props.entityType,
          };
          return params;
        };
        afterFetch = (res: relationResponse[]) => {
          let list: relationToTableItem[] = [];
          res.forEach((item: relationResponse) => {
            let tableItem: relationToTableItem = {
              type: item.type,
              toEntityType: item.to.entityType,
              toEntityName: item.toName,
              toId: item.to.id,
              jsonValue: item.additionalInfo,
              id: buildUUID(),
            };
            list.push(tableItem);
          });
          return list;
        };
        break;
      case 'to':
        tableTitle.value = '向内的关联';
        setColumns(associationToTableSchema);
        api = getRelationByTo;
        beforeFetch = () => {
          let params: relationByToParams = {
            toId: props.entityId,
            toType: props.entityType,
          };
          return params;
        };
        afterFetch = (res: relationResponse[]) => {
          let list: relationFromTableItem[] = [];
          res.forEach((item: relationResponse) => {
            let tableItem: relationFromTableItem = {
              type: item.type,
              fromEntityType: item.from.entityType,
              fromEntityName: item.fromName,
              fromId: item.from.id,
              jsonValue: item.additionalInfo,
              id: buildUUID(),
            };
            list.push(tableItem);
          });
          return list;
        };
        break;
    }
    setProps({
      api,
      beforeFetch,
      afterFetch,
      rowKey: 'id',
      rowSelection: {
        type: 'checkbox',
        selectedRowKeys: checkedKeys,
        onSelect: onSelect,
        onSelectAll: onSelectAll,
      },
    });
    reload();
  };

  const handleChange = (val) => {
    checkedKeys.value = [];
    handleRelation(val);
  };

  const handleSuccess = async ({ key, values }) => {
    if (key == 'add') {
      const promises = values.entityList.map((item) => {
        let params: saveRelationParams = {
          type: values.associationType,
          additionalInfo: values.jsonValue ? JSON.parse(values.jsonValue) : null,
          typeGroup: 'COMMON',
          from: {
            entityType: props.entityType,
            id: props.entityId,
          },
          to: {
            entityType: values.toEntity,
            id: item,
          },
        };
        if (values.optionsValue == 'to') {
          params.from = {
            entityType: values.toEntity,
            id: item,
          };
          params.to = {
            entityType: props.entityType,
            id: props.entityId,
          };
        }
        return saveRelation(params);
      });
      await Promise.all(promises);
      reload();
    } else if (key == 'edit') {
      let params: saveRelationParams = {
        type: values.record.type,
        additionalInfo: values.jsonValue ? JSON.parse(values.jsonValue) : null,
        typeGroup: 'COMMON',
        from: {
          entityType: props.entityType,
          id: values.entityId,
        },
        to: {
          entityType: values.record.toEntityType,
          id: values.record.toId,
        },
      };
      if (values.optionsValue == 'to') {
        params.from = {
          entityType: values.record.fromEntityType,
          id: values.record.fromId,
        };
        params.to = {
          entityType: props.entityType,
          id: values.entityId,
        };
      }
      await saveRelation(params);
      reload();
    }
  };

  onMounted(() => {
    setProps({
      api: getRelationByFrom,
      columns: associationFromTableSchema,
      beforeFetch: () => {
        let params: relationByFromParams = {
          fromId: props.entityId,
          fromType: props.entityType,
        };
        return params;
      },
      afterFetch: (res: relationResponse[]) => {
        let list: relationToTableItem[] = [];
        res.forEach((item: relationResponse) => {
          let tableItem: relationToTableItem = {
            type: item.type,
            toEntityType: item.to.entityType,
            toEntityName: item.toName,
            toId: item.to.id,
            jsonValue: item.additionalInfo,
            id: buildUUID(),
          };
          list.push(tableItem);
        });
        return list;
      },
      rowKey: 'id',
      rowSelection: {
        type: 'checkbox',
        selectedRowKeys: checkedKeys,
        onSelect: onSelect,
        onSelectAll: onSelectAll,
      },
    });
  });

  // 删除关联数据
  const handleDeleteRelation = async (record) => {
    let params: deleteRelationParams = {
      fromId: '',
      fromType: '',
      relationType: record.type,
      toId: '',
      toType: '',
    };
    if (record.toEntityName) {
      params.fromId = props.entityId;
      params.fromType = props.entityType;
      params.toId = record.toId;
      params.toType = record.toEntityType;
      createConfirm({
        iconType: 'info',
        title: `确定要删除实体 ${record.toEntityName} 的关联吗？`,
        content: `确定删除后实体 ${record.toEntityName} 将取消与当前实体的关联关系。`,
        onOk: async () => {
          await deleteRelation({ ...params });
          checkedKeys.value = [];
          reload();
        },
      });
    } else {
      params.fromId = record.fromId;
      params.fromType = record.fromEntityType;
      params.toId = props.entityId;
      params.toType = props.entityType;
      createConfirm({
        iconType: 'info',
        title: `确定要从实体 ${record.fromEntityName} 删除关联吗？`,
        content: `确定删除后，当前实体将与实体 ${record.fromEntityName} 取消关联`,
        onOk: async () => {
          await deleteRelation(params);
          checkedKeys.value = [];
          reload();
        },
      });
    }
  };
</script>
